package com.yan.gulimall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yan.common.utils.HttpUtils;
import com.yan.common.utils.PageUtils;
import com.yan.common.utils.Query;
import com.yan.gulimall.member.dao.MemberDao;
import com.yan.gulimall.member.dao.MemberLevelDao;
import com.yan.gulimall.member.entity.MemberEntity;
import com.yan.gulimall.member.exception.PhoneExistException;
import com.yan.gulimall.member.exception.UsernameExistException;
import com.yan.gulimall.member.service.MemberService;
import com.yan.gulimall.member.vo.MemberLoginVo;
import com.yan.gulimall.member.vo.MemberRegisterVo;
import com.yan.gulimall.member.vo.SocialUserVo;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    MemberLevelDao memberLevelDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void register(MemberRegisterVo vo) {
        MemberEntity memberEntity = new MemberEntity();
        MemberDao baseMapper = this.baseMapper;

        // 设置默认会员等级
        MemberEntity levelEntity = memberLevelDao.getDefaultLevel();
        memberEntity.setLevelId(levelEntity.getId());

        // 检查用户名和手机号是否重复,为了让Controller感知异常,使用异常机制
        checkPhoneUnique(vo.getPhone());
        checkUsernameUnique(vo.getUserName());

        memberEntity.setMobile(vo.getPhone());

        memberEntity.setUsername(vo.getUserName());
        memberEntity.setNickname(vo.getUserName());
        // 密码通过
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encodePassword = passwordEncoder.encode(vo.getPassWord());
        memberEntity.setPassword(encodePassword);


        baseMapper.insert(memberEntity);
    }

    @Override
    public void checkPhoneUnique(String phone) throws PhoneExistException {
        MemberDao baseMapper = this.baseMapper;
        Integer mobile = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone));
        if (mobile > 0) {
            throw new PhoneExistException();
        }

    }

    @Override
    public void checkUsernameUnique(String username) throws UsernameExistException {
        MemberDao baseMapper = this.baseMapper;
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", username));
        if (count > 0) {
            throw new UsernameExistException();
        }
    }

    @Override
    public MemberEntity login(MemberLoginVo vo) {

        String loginAcct = vo.getLoginAcct();
        String passWord = vo.getPassWord();

        // db查询
        MemberDao baseMapper = this.baseMapper;
        MemberEntity entity = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("username", loginAcct)
                .or().eq("mobile", loginAcct));

        if (entity == null) {
            // 没有此用户
            return null;
        } else {
            String passwordDb = entity.getPassword();
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            // 密码匹配
            boolean matches = bCryptPasswordEncoder.matches(passWord, passwordDb);
            if (matches) {
                return entity;
            } else {
                return null;
            }
        }
    }

    // 三方登陆
    @Override
    public MemberEntity login(SocialUserVo vo) throws Exception {
        String uid = vo.getUid();
        // 判断当前社交用户是否已经登录过
        MemberDao baseMapper = this.baseMapper;
        MemberEntity social_uid = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", uid));
        if (social_uid != null) {
            // 该用户已经通过第三方账号进行登陆过
            MemberEntity memberEntity = new MemberEntity();
            memberEntity.setId(social_uid.getId());
            memberEntity.setAccess_Token(social_uid.getAccess_Token());
            memberEntity.setExpires_In(social_uid.getExpires_In());

            baseMapper.updateById(memberEntity);
            social_uid.setAccess_Token(social_uid.getAccess_Token());
            social_uid.setExpires_In(social_uid.getExpires_In());
            return social_uid;
        } else {
            // 未进行第三方登陆过,需要注册操作
            MemberEntity register = new MemberEntity();
            try {

                Map<String, String> query = new HashMap<>();
                query.put("access_token", social_uid.getAccess_Token());
                query.put("uid", social_uid.getSocial_Uid());
                HttpResponse response = HttpUtils.doGet("https:api.weibo.com", "/2/users/show.json", "get", new HashMap<String, String>(), query);

                if (response.getStatusLine().getStatusCode() == 200) {
                    // 查询成功
                    String s = EntityUtils.toString(response.getEntity());
                    JSONObject jsonObject = JSON.parseObject(s);
                    // 获取三方api中的用户信息进行注册
                    String name = jsonObject.getString("name");
                    String gender = jsonObject.getString("gender");
                    register.setNickname(name);
                    register.setGender("m".equals(gender) ? 1 : 0);

                }
            } catch (Exception e) {
            }
            register.setSocial_Uid(uid);
            register.setAccess_Token(social_uid.getAccess_Token());
            register.setExpires_In(social_uid.getExpires_In());
            baseMapper.insert(register);

            return register;

        }

    }
}